<?php 

/***********************************************************************
*
* SECTION common
* functions for handling generic tasks, very useful; stuff that
* really should come with PHP by default, but whatever.
*
***********************************************************************/
function in_string ($needle, $haystack, $insensitive = 0) {
   if ($insensitive) {
      return (false !== stristr($haystack, $needle)) ? true : false;
   } else {
      return (false !== strpos($haystack, $needle)) ? true : false;
   }
}



/***********************************************************************
*
* SECTION user
* functions for handling users, passwords, rights, and the like
* often associated with ./mode/user.inc
*
***********************************************************************/
function mkUsrPasswd ($username, $passwd) {
   return md5(strtolower(trim($username)).strtolower(trim($passwd)));
}



/***********************************************************************
*
* SECTION files
* functions for handling files & meta-tags.
*
***********************************************************************/



// getTrkId3() function
//
// Description: 
// This function uses getId3_lib::CopyTagsToComments(), specifically the returned comments_html array 
// to retrieve tags information from files in a semi-stable manner 
// 
// inputs:
// 1. string filename of file from which to retrieve tags 
//
// outputs:
// 1. an array with file information/metadata
//    Array Structure:
//    $array[category] (id of the file's main category)
//          [artist]
//          [album]
//          [num] (track number)
//          [title] (track title)
//          [virtue] requred to sort outside of UNSORTED dir 
//          [status] required to save outside of UNSORTED dir
//          [bitrate]
//          [ext] (filename extension)
//          [filesize]
//          [status]
//          [genre]
//          [playtime]
//          [filepath]
//          [filename]
// 3. destination directory 
//
// Outputs:
// an array with the file name and directory on success; false on failure.

function getTrkId3 ($file) {
   include_once('./includes/getid3-1.7.8b1/getid3/getid3.php');
   $fileTypes = array('mp3','ogg','wmv','asf','flac','wma','wav','aac','m4a'); // for now, m4a doesn't seem to work... 
   $fileInfo = pathinfo($file); // grab path and file names for the file; returns an array with 'dirname','basename','extension', and 'filename'
   $ext = strtolower($fileInfo[extension]);
   if(in_array($ext,$fileTypes)) {
      
      // initialize a new getID3 object
      $getID3 = new getID3;
      
      // use getid3's analyze function to examine the incoming file 
      $trackInfo = $getID3->analyze($incomingDir.$file);
      
      // getid3's CopyTagsToComments function can take the snagged metadata and put it into an array marked as 'comments_html'
      getid3_lib::CopyTagsToComments($trackInfo);
      
      // put the relevant comments_html array data into a simpler array called $trkFile, which we'll use throughout the program 
      $trk['title'] = (isset($trackInfo['comments_html']['title'][0]) ? $trackInfo['comments_html']['title'][0] : "");
      
      // make a few attempts at getting the track artist name 
//      $trk['artist'] = (isset($trackInfo['comments_html']['artist'][0]) ? $trackInfo['comments_html']['artist'][0] : "");
      if ( isset($trackInfo['comments_html']['artist'][0]) ) {
         $trk['artist'] = $trackInfo['comments_html']['artist'][0];
      } else if ( isset($trackInfo['comments_html']['TPE1'][0]) ) {
         $trk['artist'] = $trackInfo['comments_html']['TPE1'][0];
      } else if ( isset($trackInfo['comments_html']['©ART'][0]) ){
         $trk['artist'] = $trackInfo['comments_html']['©ART'][0];
      } else {
         $trk['artist'] = "";
      }
      
      
      $bitrate = explode(".",($trackInfo['audio']['bitrate']/1000));
      $trk['bitrate'] = $bitrate[0]."k";
      $trk['playtime'] = date("H:i:s", mktime(0,0,$trackInfo['playtime_seconds']));
      $trk['genre'] = (isset($trackInfo['comments_html']['genre'][0]) ? $trackInfo['comments_html']['genre'][0] : "");
      
      // try a number of different common tag names for snagging a track number 
      if ( isset($trackInfo['comments_html']['tracknumber'][0]) ) {
         $trk['num'] = $trackInfo['comments_html']['tracknumber'][0];
      } else if ( isset($trackInfo['comments_html']['track_number'][0]) ){
         $trk['num'] = $trackInfo['comments_html']['track_number'][0];
      } else if ( isset($trackInfo['comments_html']['TRCK'][0]) ) {
         $trk['num'] = $trackInfo['comments_html']['TRCK'][0];
      } else if ( isset($trackInfo['comments_html']['trkn'][0]) ) {
         $trk['num'] = $trackInfo['comments_html']['trkn'][0];
      } else {
         $trk['num'] = (isset($trackInfo['comments_html']['track'][0]) ? $trackInfo['comments_html']['track'][0] : "");
      }
      if (in_string('/', $trk['num'], 1)) {
         $trkNumTmp = explode('/', $trk['num']);
         $trk['num'] = $trkNumTmp[0];
      }
      
      
      $trk['album'] = (isset($trackInfo['comments_html']['album'][0]) ? $trackInfo['comments_html']['album'][0] : "");
      $trk['filepath'] = (isset($trackInfo['filepath']) ? $trackInfo['filepath'] : "");
      if (!$trk['filepath']) $trk[filepath] = $fileInfo[dirname];
      // append the trailing slash if it's not there. 
      //if ( ($trkFile[$i]['filepath'][((strlen($trkFile[$i]['filepath'])) - 1)]) !== '/' ) $trkFile[$i]['filepath'] .= '/';
      $trk[filename] = (isset($trackInfo[filename]) ? $trackInfo[filename] : "");
      if (!$trk[filename]) $trk[filename] = $fileInfo[basename];
      
      $trk['ext'] = $ext;
     	$trk['filesize'] = filesize($incomingDir.$file);
      if (!$trk['status']) $trk[status] = 1;
      
      if (!$trk[num] && !$trk[title] && !$trk[album]) {
         return false;
      } else {
         return $trk;
      }
      
      
   } else {
      return false;
   }   
}

// mvTrkFile() function
//
// Description: 
// This function moves files from the "incoming" directory to the outgoing directory,
// changing names and creating folders as appropriate (to have a consistent naming system)
// 
// inputs:
// 1. the existing file name
// 2. an array with file information/metadata
//    Array Structure:
//    $array[category] (id of the file's main category)
//          [artist]
//          [album]
//          [num] (track number)
//          [title] (track title)
//          [virtue] requred to sort outside of UNSORTED dir 
//          [status] required to save outside of UNSORTED dir
// 3. destination directory 
//
// Outputs:
// an array with the file name and directory on success; false on failure.
function mvTrkFile ($oldFile, $fileInfo, $outgoingDir = '/var/music/') {   
   
   if (file_exists($oldFile)) {
      
      if (!$outgoingDir) $outgoingDir = '/var/music/';
      if ($outgoingDir[(count($outgoingDir)-1)] != '/') $outgoingDir .= '/';
      
      //set umask properly so that chmodding works properly in all configurations
      $old_umask = umask(0);
      
      if (!is_dir($outgoingDir)) mkdir($outgoingDir, 0744);
      
      if ($fileInfo['status'] > 1) {
         if (ctype_digit($fileInfo['category'])) {
            $catQuery = mysql_query("SELECT `filename` FROM `category` WHERE `id`='".$fileInfo['category']."' LIMIT 1");
            $category = mysql_result ($catQuery, 0);
         }
         
         if (!$fileInfo[virtue] || $fileInfo[virtue] == 0) {
            $ougoingDir .= 'UNSORTED/';
         } else if ($fileInfo[virtue] > 3) {
            $outgoingDir .= 'PRIME/';
         } else if ($fileInfo[virtue] > 1) {
            $outgoingDir .= 'CLEAN/';
         } else {
            $outgoingDir .= 'FCC_UNCLEAN/';
         }
         if (!is_dir($outgoingDir)) mkdir($outgoingDir, 0744);
         
         if ($category) $outgoingDir = $outgoingDir.$category.'/';
         else $outgoingDir = $outgoingDir.'default/';
         
      } else {
         $outgoingDir .= 'UNSORTED/';
      }
      
      if (!is_dir($outgoingDir)) mkdir($outgoingDir, 0744);
      
      //sanitize album, artist, and title
      $replace = array('\\','/','(',')','<','>',':',';','&','!','?'); 
      // "\/", "\", '<', '>', '{', '}', '[', ']', , '~', '`', '%', "*" );
      str_replace($replace, '_', $fileInfo['artist']);
      $artist = strtolower(str_replace($replace, '_', $fileInfo['artist']));
      $album = strtolower(str_replace($replace, '_', $fileInfo['album']));
      if ($fileInfo['num'] < 10) $fileInfo['num'] = '0'.$fileInfo['num'];
      $filename = strtolower($fileInfo['num'] . ' - ' .str_replace($replace, '_', $fileInfo['title']) . '.' . array_pop(explode(".",$oldFile)));
      
      //check if directory exists, if not, add it
      if (!is_file($outgoingDir.$artist.'/'.$album.'/'.$title)) {
         if (!is_dir($outgoingDir.$artist.'/'.$album)) {
            if (!is_dir($outgoingDir.$artist)) mkdir($outgoingDir.$artist, 0744);
            mkdir($outgoingDir.$artist.'/'.$album . '/', 0744);
         }
      }
      //format the title to make it work for a filename 
      $path = $outgoingDir.$artist.'/'.$album.'/';
      $newFilename = $path.$filename;
   
      if (rename($oldFile, $newFilename)) {
         // try to protect the file with permissions changes 
         @chmod($newFilename, 0744);
         $success = true;
      }
      else unset($success);
   
      //set umask back to what it was just in case.
      umask($old_umask);
      if ($success) {
      $filenameArray[filepath] = "$path";
      $filenameArray[filename] = "$filename";
      return $filenameArray;
      } else {
         return NULL;
      }
   } else {
      return NULL;
   }
}

// getDirFiles ()
// scans a directory recursively for files and outputs them as an array. 
//
function getDirFiles ($path = '/var/music/INCOMING/') {
   if (!is_dir($path)) return 0;
   $list=array();
   $dir = @opendir("$path");
   while ($file= @readdir($dir)) {
      if (($file<>".")&&($file<>"..")) {
         $f=$path."/".$file;
         $f=preg_replace('/(\/){2,}/','/',$f); //replace double slashes
         if(is_file($f)) $list[]=$f;
         if(is_dir($f)) $list = array_merge($list, getDirFiles($f));
      }
   }
   @closedir($dir); 
   return $list ;
}


// rmEmpty function scans all directories in the given directory and
// deletes all the empty directories.  scandir() subfunction requires php > version 5
// 
// Inputs:
// 1. master directory, as a string (including trailing slash).
// 
// Outputs:
// 1. bool/string 'true' for success, 'false' for error/failure.
//
// {{{not entirely sure yet if it deletes non-empty directories on windows machines}}}
function rmEmpty ($rootDir = "/var/music/INCOMING/", $dir = '/var/music/INCOMING/') { //($rootDir = '/var/music/INCOMING/', $dir = '/var/music/INCOMING/') {
   $dirContents = scandir($dir);
   if ($dirContents) {
      foreach ($dirContents as $item) {
         if (is_dir($dir.$item) && $item != '.' && $item != '..' && ($item != $dir) && ($item != $dir.'.') ) {
            rmEmpty($rootDir, $dir.$item.'/');
         } // end if (is_dir($dir.$item)... 
      } // end foreach ($dirContents as $item) 
   } // end if ($dirContents)
   // rmdir removes the directory if it is empty.  the '@' prevents the function from reporting errors when it fails trying to delete directories with contents.
   if ($dir !== $rootDir) {
      @rmdir($dir);
   }
}


/****************************************************************
*
* SECTION misc
* Miscellaneous functions
*
****************************************************************/

// this function just truncates strings
function trunc( $str, $num = 20 ) {
  if( strlen( $str ) > $num ) $str = substr( $str, 0, $num ) . "...";
  return $str;
}


//this function just unsets all the global variables (used in logout)
function unset_all_vars($a){ 
	foreach($a as $key => $val){ 
		unset($GLOBALS[$key]); 
	}
	return serialize($a); 
}

function get_spins($CD_id,  $min_date = 0, $max_date = 0) {
	if (!$min_date) $min_date = date("Y-m-d H:i:s", mktime(date('H'), date('i'), date('s'), date('m'), date('d') - 7, date('Y')));
	if (!$max_date) $max_date = date("Y-m-d H:i:s");
	if ($result = @mysql_result(mysql_query("SELECT COUNT(`cddbid`) FROM `airplay` WHERE `cddbid`='".mysql_real_escape_string($CD_id)."' AND `timestamp`<='".mysql_real_escape_string($max_date)."' AND `timestamp`>='".mysql_real_escape_string($min_date)."' "), 0)) return ($result);
	else {
		return 0;
	}
}

function get_weeks($CD_id) {
	$get_weeks_statement = "SELECT `add_date` FROM `album` WHERE `cddbid`='".mysql_real_escape_string($CD_id)."' LIMIT 1";
	$get_weeks_query = mysql_query($get_weeks_statement);
	$get_weeks_result = @mysql_fetch_row($get_weeks_query);
	$switchDate = date('Y-m-d');
	if  ($get_weeks_result[0] && $get_weeks_result[0] !== '0000-00-00' && $get_weeks_result[0] <= $switchDate) {
		echo ($today);
		for ($i = 0; $switchDate >= $get_weeks_result[0];$i++) {
			$switchDate = date('Y-m-d', mktime(date('H'), date('i'), date('s'), date('m'), date('d') - $i, date('Y')));
		}
		$weeks = round($i/7);
		return $weeks;
	} else {
		return 0;
	}
}

function get_heavy($min_datetime, $max_datetime) {
	$get_heavy_statement = "SELECT `cddbid` FROM `airplay` WHERE `status`<='2' AND `cddbid`!='' AND `timestamp`>'".$min_datetime."' AND `timestamp`<='".$max_datetime."' " ;
	$get_heavy_result = mysql_query($get_heavy_statement);
	while ($get_heavy_row = mysql_fetch_array($get_heavy_result)) {
		if ($this_is_temporary) {
			
		}
	}
//while($stat_row = mysql_fetch_assoc($stat_result)) {
//	$temp_query = "SELECT * FROM `temp_stat` WHERE `cdid`='".$stat_row[cddbid]."' LIMIT 1";
//	$temp_result = mysql_query($temp_query) or die(mysql_error());	
//	if ($temp_row = mysql_fetch_assoc($temp_result)) {
//		$spins = $temp_row[spins];
//		$spins++;
//		mysql_query("UPDATE `temp_stat` SET `spins`='".$spins."' WHERE `cdid`='".$stat_row[cddbid]."' ") or die(mysql_error());
//	} else {
//		mysql_query("INSERT INTO `temp_stat` SET `spins`='1', `cdid`='".$stat_row[cddbid]."' ") or die(mysql_error());
//	}
//}
//$rating = 0;
//$statistics_query = "SELECT * FROM `temp_stat` ORDER BY `spins` DESC";
//$statistics_result = mysql_query($statistics_query) or die(mysql_error());
//while ($statistics_row = mysql_fetch_assoc($statistics_result)) {
}



/***********************************************************************
*
* SECTION traffic
* functions for handling tasks related to traffic or airplay logging
*
***********************************************************************/

// 
// function addAir()
// 
// 
// 
// 
function addAir ($s, $dataType, $req) {
//   switch ($dataType)
   return $airId;
}

/***********************************************************************
*
* SECTION statistics
* functions for handling traffic statistical tasks, such as CMJ reports
*
***********************************************************************/

// 
// function airAlbRank()
// 
// this function returns an array with the albId of the most-often played
// albums according to the airplay table. Albums are returned along with 
// their spin counts for the defined period of time 
// 
// inputs: 
// 1. the minimum date-time ("YYYY-MM-DD HH:ii:ss" format) for checking spins from airplay
// 2. the maximum date-time for checking spins from airplay
// 3. maximum number of album results to return (int) 
// 3. optional category ID# to poll database results from (int) 
// 4. optional status limiter for returned results (int) 
// 5. optional minimum add date for returned results (YYYY-MM-DD) 
// 6. optional requirement to only track requests (bool)
// 
// outputs:
// 

function airAlbRank ($airMin = false, $airMax = false, $maxAlb = false, $cat = false, $status = false, $addDateMin = false, $reqOnly = false) {
   
   if (!$airMin) $airMin = '0000-00-00';
   $statSql = "SELECT `cddbid`,`add_date` FROM `airplay` WHERE (`timestamp`>'".$airMin."') AND (`cddbid` != '0') ";
   
   if ($reqOnly) $statSql .= " AND (`request` = '1') ";
   
   if ($cat && ($cat !== 'all') ) {
      $statSql .= " 
         AND 
         ( 
            (`category`='".$cat."') 
            OR 
            (`category2`='".$cat."') 
            OR 
            (`category3`='".$cat."')
         )";
   }
   
   // for now, we'll hack this as the add date 
   //$thirteen_weeks_ago = date('Y-m-d', mktime(date(H), date(i), date(s), date(m)-3, date(d), date(Y)));
   
   //if (!$_REQUEST[addDateMin] && !$addDateMin) $addDateMin = $thirteen_weeks_ago;
   //'0000-00-00';
   //else $addDateMin = $_REQUEST[addDateMin];
   
   $statSql .= " AND (`add_date`>='".$addDateMin."') ";
   $statSqlOrderBy = " ORDER BY `cddbid` DESC ";
//   echo($statSql.$statSqlOrderBy);
   $statQuery = mysql_query($statSql.$statSqlOrderBy);
   
   $i = -1;
   while ($stat = mysql_fetch_array($statQuery)) {
      if ($stat[cddbid] == $cmj[$i][albId]) {
         $cmj[$i][addDate] = $stat[add_date]; // FYI: this will overwrite add-date discrepancies with the latest/updated ones for all instances 
         $cmj[$i][spins]++;
      } else {
         $i++;
         $cmj[$i][albId] = $stat[cddbid];
         $cmj[$i][addDate] = $stat[add_date];
         $cmj[$i][spins] = 1;
      }
   }
   
   if ($cmj) {
      // swap database data into columns, because arraymultisort needs them
      foreach ($cmj as $key => $row) {
         $albId[$key]  = $row['albId'];
         $spins[$key] = $row['spins'];
         $addDate[$key] = $row['addDate'];
      }
      // array_multisort() returns the columns as an array, with the most spin counts first
      @array_multisort($spins, SORT_DESC, $addDate, SORT_DESC, $albId, SORT_DESC, $cmj);
      return $cmj;
      
   } else {
      echo ('Nothing meeting those conditions got any spins. <br />');
   }
}

?>